package com.weifly.weistock.core.util.grid;

import com.weifly.weistock.core.common.StockException;
import com.weifly.weistock.core.util.WeistockUtils;

import java.util.ArrayList;
import java.util.List;

/**
 * 用于生成网格价格列表
 *
 * @author weifly
 * @since 2019/8/13
 */
public class GridPriceGenerator {

    private double minPrice; // 最小价格
    private double maxPrice; // 最大价格
    private double basePrice; // 基准价格
    private double minStepPrice; // 最小变动价格
    private double step = 1.0; // 网格价差，百分比

    public double getMinPrice() {
        return minPrice;
    }

    public void setMinPrice(double minPrice) {
        this.minPrice = minPrice;
    }

    public double getMaxPrice() {
        return maxPrice;
    }

    public void setMaxPrice(double maxPrice) {
        this.maxPrice = maxPrice;
    }

    public double getBasePrice() {
        return basePrice;
    }

    public void setBasePrice(double basePrice) {
        this.basePrice = basePrice;
    }

    public double getMinStepPrice() {
        return minStepPrice;
    }

    public void setMinStepPrice(double minStepPrice) {
        this.minStepPrice = minStepPrice;
    }

    public double getStep() {
        return step;
    }

    public void setStep(double step) {
        this.step = step;
    }

    /**
     * 生成网格价格列表，高价在前
     */
    public List<GridPricePoint> generateGridPriceList(){
        if(this.minPrice==0){
            throw new StockException("缺少参数：minPrice");
        }
        if(this.maxPrice==0){
            throw new StockException("缺少参数：maxPrice");
        }
        if(this.basePrice==0){
            throw new StockException("缺少参数：basePrice");
        }
        if(this.minStepPrice<=0){
            throw new StockException("缺少参数：minStepPrice");
        }
        if(this.step<=0){
            throw new StockException("缺少参数：step");
        }

        List<GridPricePoint> gridPriceList = new ArrayList<>();
        this.makeHighPrice(gridPriceList);
        this.makeLowPrice(gridPriceList);
        return gridPriceList;
    }

    private void makeHighPrice(List<GridPricePoint> gridPriceList){
        // 基准价点
        GridPricePoint basePoint = new GridPricePoint();
        basePoint.setPrice(this.basePrice);
        gridPriceList.add(0, basePoint);
        // 找高位价点
        double nowPrice = this.basePrice;
        double nextPrice = nowPrice;
        while(nextPrice<=this.maxPrice){
            nextPrice = WeistockUtils.add(nextPrice, this.minStepPrice);
            double nowDiff = WeistockUtils.subtract(nextPrice, nowPrice);
            double nowStep = WeistockUtils.divide(WeistockUtils.multi(nowDiff, 100), nowPrice);
            if(nowStep>=this.step){
                // 满足条件
                GridPricePoint newPoint = new GridPricePoint();
                newPoint.setPrice(nextPrice);
                newPoint.setDiff(nowDiff);
                newPoint.setStep(nowStep);
                gridPriceList.add(0, newPoint);
                // 更新价点
                nowPrice = nextPrice;
            }
        }
    }

    private void makeLowPrice(List<GridPricePoint> gridPriceList){
        GridPricePoint nowPoint = gridPriceList.get(gridPriceList.size()-1);
        double nowPrice = nowPoint.getPrice();
        double prePrice = nowPrice;
        while(prePrice>=this.minPrice){
            prePrice = WeistockUtils.subtract(prePrice, this.minStepPrice);
            double nowDiff = WeistockUtils.subtract(nowPrice, prePrice);
            double nowStep = WeistockUtils.divide(WeistockUtils.multi(nowDiff, 100), prePrice);
            if(nowStep>=this.step){
                // 满足条件
                nowPoint.setDiff(nowDiff);
                nowPoint.setStep(nowStep);
                // 新节点
                nowPoint = new GridPricePoint();
                nowPoint.setPrice(prePrice);
                gridPriceList.add(nowPoint);
                // 更新价点
                nowPrice = prePrice;
            }
        }
    }
}
